<template>
  <div class="upline-timeline-drawer">
    <div class="upline-drawer-body">
      <div ref="docTimelineLegend" class="upline-timeline-legend">
        <div
          v-for="(item, index) in DATA"
          :key="index"
          class="upline-selectable"
          :style="
            'background-color:' +
            (index === 0
              ? selfTeamColor
              : teamColorList[(index - 1) % teamColorList.length])
          "
        >
          {{ item.groupName }}
        </div>
      </div>
    </div>
    <div class="upline-pull-tab">
      <div ref="docTimelineCanvas" class="upline-timeline-canvas">
        <div ref="docTimelineLeft"></div>
        <canvas ref="docCanvas"></canvas>
        <div ref="docTimelineRight"></div>
      </div>
      <div class="upline-scroll-bar">
        <div class="upline-scroll-button upline-clickable upline-go-left">
          <img src="@/assets/images/design/goFarLeft.png" />
        </div>
        <div class="upline-scroll-button upline-clickable upline-go-left">
          <img src="@/assets/images/design/goLeft.png" />
        </div>
        <div ref="docSlider" class="upline-slider">
          <div
            ref="docLeftDrag"
            class="upline-left-drag upline-scroll-button upline-clickable"
          >
            <div class="line"></div>
          </div>
          <div ref="docGrip" class="upline-grip upline-clickable"></div>
          <div
            ref="docRightDrag"
            class="upline-right-drag upline-scroll-button upline-clickable"
          >
            <div class="line"></div>
          </div>
          <div ref="docLeftDragTime" class="upline-left-drag-time"></div>
          <div ref="docRightDragTime" class="upline-right-drag-time"></div>
        </div>
        <div class="upline-scroll-button upline-clickable upline-go-right">
          <img src="@/assets/images/design/goRight.png" />
        </div>
        <div class="upline-scroll-button upline-clickable upline-go-right">
          <img src="@/assets/images/design/goFarRight.png" />
        </div>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
  import { onMounted, getCurrentInstance, ref, watch } from 'vue';
  import { TimeNode, TimeListTypes } from '../api';
  import getTimeArray from '../event/getTimeArray';
  import {
    formateDate,
    getStartEndTime,
    getTimeText,
    disableImageSelection,
  } from '../event/utils';
  import CONSTANT from '../json/constant.json';
  import {
    drawMark,
    drawEvent,
    getUploadMap,
    UPLOAD_TYPES,
    getMarkText,
  } from '../event/draw';
  import { FUNCTION_TYPES, getFunctionType } from '../event/uploadClick';

  const props = defineProps({
    data: {
      type: Array,
      default() {
        return [];
      },
    },
  });

  // 根据DATA计算得出的常量
  let START_TIME: Date; // 最先上传时间
  let END_TIME: Date; // 最后上传时间
  let TOTAL_TIME: number; // 上传时间总间隔
  let EACH_TIME_ARRAY: TimeListTypes; // 分别以年/月/日/小时为单位分割时间线得到的数组

  // html元素
  let docCanvas: HTMLCanvasElement;
  let docCtx: CanvasRenderingContext2D;
  let docTimelineCanvas: HTMLElement;
  let docLeftDrag: HTMLElement;
  let docRightDrag: HTMLElement;
  let docGrip: HTMLElement;
  let docSlider: HTMLElement;
  let docTimelineLegend: HTMLElement;
  let docLeftDragTime: HTMLElement;
  let docRightDragTime: HTMLElement;
  let docTimelineLeft: HTMLElement;
  let docTimelineRight: HTMLElement;

  // 变量
  let left = 0; // 左侧拖动按钮位置百分比
  let right = 1; // 右侧拖动按钮位置百分比
  let draglayerX = 0; // 中间滑块鼠标按下时偏移量
  let leftTime: Date; // 左侧拖动按钮表示时间
  let rightTime: Date; // 右侧拖动按钮表示时间
  let smallMarginLeft = 0;
  let smallMarginRight = 0;

  const eventMap = new Map(); // 存放event

  const lineHeight = ref(`${CONSTANT.LINE_HEIGHT}px`);
  const lineWeight = ref(`${CONSTANT.LINE_WEIGHT}px`);
  const teamColorList = ref(CONSTANT.TEAM_COLOR_LIST);
  const selfTeamColor = ref(CONSTANT.SELF_TEAM_COLOR);

  const DATA = ref<any[]>([]);

  /**
   * @description 获取页面元素
   */
  function getDoc() {
    const pageInstance = getCurrentInstance();
    docCanvas = pageInstance?.refs.docCanvas as HTMLCanvasElement;
    docCtx = docCanvas.getContext('2d') as CanvasRenderingContext2D;
    docTimelineCanvas = pageInstance?.refs.docTimelineCanvas as HTMLElement;
    docLeftDrag = pageInstance?.refs.docLeftDrag as HTMLElement;
    docRightDrag = pageInstance?.refs.docRightDrag as HTMLElement;
    docGrip = pageInstance?.refs.docGrip as HTMLElement;
    docSlider = pageInstance?.refs.docSlider as HTMLElement;
    docTimelineLegend = pageInstance?.refs.docTimelineLegend as HTMLElement;
    docLeftDragTime = pageInstance?.refs.docLeftDragTime as HTMLElement;
    docRightDragTime = pageInstance?.refs.docRightDragTime as HTMLElement;
    docTimelineLeft = pageInstance?.refs.docTimelineLeft as HTMLElement;
    docTimelineRight = pageInstance?.refs.docTimelineRight as HTMLElement;
  }

  /**
   * @description 初始化画布两边背景
   */
  function setCanvasMarginBackground() {
    while (docTimelineLeft.children.length > 0) {
      docTimelineLeft.children[0].remove();
    }
    while (docTimelineRight.children.length > 0) {
      docTimelineRight.children[0].remove();
    }
    for (let i = 0; i < DATA.value.length; i++) {
      const backgroundColor =
        i === 0
          ? CONSTANT.SELF_TEAM_COLOR
          : CONSTANT.TEAM_COLOR_LIST[(i - 1) % CONSTANT.TEAM_COLOR_LIST.length];
      const line1 = document.createElement('div');
      line1.style.height = `${CONSTANT.LINE_WEIGHT}px`;
      line1.style.width = `${CONSTANT.LINE_MARGIN}px`;
      line1.style.backgroundColor = backgroundColor;
      line1.style.marginTop =
        i === 0
          ? `${1.5 * CONSTANT.LINE_HEIGHT}px`
          : `${2 * CONSTANT.LINE_HEIGHT - CONSTANT.LINE_WEIGHT}px`;
      docTimelineLeft.appendChild(line1);
      const line2 = document.createElement('div');
      line2.style.height = `${CONSTANT.LINE_WEIGHT}px`;
      line2.style.width = `${CONSTANT.LINE_MARGIN}px`;
      line2.style.backgroundColor = backgroundColor;
      line2.style.marginTop =
        i === 0
          ? `${1.5 * CONSTANT.LINE_HEIGHT}px`
          : `${2 * CONSTANT.LINE_HEIGHT - CONSTANT.LINE_WEIGHT}px`;
      docTimelineRight.appendChild(line2);
    }
  }

  /**
   * @description 初始化画布和滚动条
   */
  function initCanvasAndScroll() {
    // 初始化画布两边背景
    setCanvasMarginBackground();
    // 初始化画布
    docCanvas.height = (2 * DATA.value.length + 1) * CONSTANT.LINE_HEIGHT;
    docCanvas.width = docTimelineCanvas.clientWidth - CONSTANT.LINE_MARGIN * 2; // 40为side背景宽度
    // 滑块区域宽度
    const sliderWidth = docSlider.offsetWidth;
    // 初始化可视化组件
    docRightDrag.style.left = `${sliderWidth}px`;
    docLeftDrag.style.left = '0';
    docGrip.style.left = '0';
    docGrip.style.width = `${sliderWidth}px`;
  }

  /**
   * @description 绘制矩形（背景-时间）
   * @param {*} offset 偏移量（百分比）
   * @param {*} times 放大倍数
   * @param {*} timeArray 时间间隔数组
   * @param {*} timeType 时间类型（年/月/日/小时）
   */
  function drawRect(
    offset: number,
    times: number,
    timeArray: TimeNode[],
    timeType: string
  ) {
    let leftPointer = 0;
    for (let i = 0; i < timeArray.length; i++) {
      const rectWidth =
        (docCanvas.width * (timeArray[i].interval as number)) / times;
      const rectLeft = leftPointer - (offset * docCanvas.width) / times;
      // 判断是否在绘制区域内（性能优化）
      if (rectLeft < docCanvas.width && rectLeft > -docCanvas.width) {
        // 绘制rect
        docCtx.fillStyle =
          i % 2 === 0
            ? CONSTANT.BACKGROUND_COLOR_1
            : CONSTANT.BACKGROUND_COLOR_2;
        docCtx.fillRect(rectLeft, 0, rectWidth, docCanvas.height);
        // 绘制时间text
        docCtx.fillStyle = 'rgb(187, 187, 187)';
        docCtx.font = `${CONSTANT.TIME_TEXT_SIZE}px Arial`;
        const text = getTimeText(timeArray[i].startTime as Date, timeType);
        const textWidth = docCtx.measureText(text).width;
        // 判断react长度够不够显示text
        if (textWidth < rectWidth) {
          const textTop =
            DATA.value.length % 2 === 0
              ? (DATA.value.length + 0.5) * CONSTANT.LINE_HEIGHT +
                CONSTANT.TIME_TEXT_SIZE / 2
              : (DATA.value.length - 0.5) * CONSTANT.LINE_HEIGHT +
                CONSTANT.TIME_TEXT_SIZE / 2;
          docCtx.fillText(
            text,
            rectLeft + rectWidth / 2 - textWidth / 2,
            textTop
          );
        }
      }
      leftPointer += rectWidth;
    }
  }

  /**
   * @description 绘制时间线
   */
  function drawLine() {
    DATA.value.forEach((item: any, index: number) => {
      const color =
        index === 0
          ? CONSTANT.SELF_TEAM_COLOR
          : CONSTANT.TEAM_COLOR_LIST[
              (index - 1) % CONSTANT.TEAM_COLOR_LIST.length
            ];
      docCtx.beginPath();
      docCtx.moveTo(
        0,
        (2 * index + 1.5) * CONSTANT.LINE_HEIGHT + CONSTANT.LINE_WEIGHT / 2
      );
      docCtx.lineTo(
        docCanvas.width,
        (2 * index + 1.5) * CONSTANT.LINE_HEIGHT + CONSTANT.LINE_WEIGHT / 2
      );
      docCtx.lineWidth = 2;
      docCtx.strokeStyle = color;
      docCtx.setLineDash([5, 10, 20]);
      docCtx.lineDashOffset = -50;
      docCtx.stroke();
    });
  }

  /**
   * @description 设置leftDrag的时间点
   */
  function setLeftDragTime() {
    leftTime = new Date(START_TIME.getTime() + left * TOTAL_TIME);
    docLeftDragTime.innerText = formateDate(leftTime);
    docLeftDragTime.style.left = docLeftDrag.style.left;
  }

  /**
   * @description 设置rightDrag的时间点
   */
  function setRightDragTime() {
    rightTime = new Date(START_TIME.getTime() + right * TOTAL_TIME);
    docRightDragTime.innerText = formateDate(rightTime);
    docRightDragTime.style.left = docRightDrag.style.left;
  }

  let draw: any;

  function combinationEventClick(timeA: Date, timeB: Date) {
    smallMarginLeft = 0;
    smallMarginRight = 0;
    // const sliderWidth = docSlider.offsetWidth;
    left = (timeA.getTime() - START_TIME.getTime()) / TOTAL_TIME;
    right = (timeB.getTime() - START_TIME.getTime()) / TOTAL_TIME;
    // docGrip.style.left = `${sliderWidth * left}px`;
    // docGrip.style.width = `${sliderWidth * (right - left)}px`;
    // docLeftDrag.style.left = `${sliderWidth * left}px`;
    // docRightDrag.style.left = `${sliderWidth * right}px`;
    draw(left, right - left);
  }

  function setFunction(ele: HTMLElement, history: any) {
    const type = getFunctionType(history);
    if (type.type === FUNCTION_TYPES.TYPE_99) {
      ele.addEventListener('click', () => {
        combinationEventClick(type.startTime, type.endTime);
      });
    }
  }

  /**
   * @description 绘制上传的文件
   */
  function drawUpload(times: number) {
    const totalTime = rightTime.getTime() - leftTime.getTime();
    const historyMapKeys: Date[] = [];
    DATA.value.forEach((team: any, index: number) => {
      team.historyMap = getUploadMap(
        team.uploadHistory,
        times,
        TOTAL_TIME,
        docCanvas.width,
        index
      );
      team.historyMap.forEach((history: any, key: Date) => {
        const eventItem = eventMap.get(history.uploadTime);
        historyMapKeys.push(history.uploadTime);
        // 在显示范围内
        if (history.uploadTime >= leftTime && history.uploadTime <= rightTime) {
          const marginLeft =
            (history.uploadTime.getTime() - leftTime.getTime()) / totalTime;
          const eventLeft =
            marginLeft * docCanvas.width +
            CONSTANT.LINE_MARGIN -
            CONSTANT.RECT_WIDTH / 2;
          const childrenLength =
            'children' in history && getMarkText(history.children);
          // 维护eventMap
          if (eventItem) {
            eventItem.style.left = `${eventLeft}px`;
            // 如果形状变化 重新绘制
            const beforeHistory = team.beforeHistoryMap?.get(key);
            if (beforeHistory?.type !== history.type) {
              eventItem.style.width = '0';
              eventItem.style.height = '0';
              const mark: any = eventItem.children[0];
              if (mark) {
                mark.style.opacity = '0';
              }
              setTimeout(() => {
                eventItem.remove();
              }, 200);
              const event = document.createElement('div');
              // 绘制
              drawEvent(event, eventLeft, index, history.type);
              // 添加事件
              setFunction(event, history);
              docTimelineCanvas.appendChild(event);
              eventMap.set(history.uploadTime, event);
              if (
                'children' in history &&
                history.type !== UPLOAD_TYPES.TYPE_12 &&
                childrenLength &&
                childrenLength > 1
              ) {
                const newMark = document.createElement('div');
                drawMark(newMark);
                newMark.innerHTML = `${childrenLength}`;
                event.appendChild(newMark);
              }
            } else {
              // 形状没有变化
              // 如果元素上没有mark，新数据又有children，则新增mark
              if (
                'children' in history &&
                !eventItem.children[0] &&
                childrenLength &&
                childrenLength > 1
              ) {
                const mark = document.createElement('div');
                // 绘制
                drawMark(mark);
                mark.innerHTML = `${childrenLength}`;
                eventItem.appendChild(mark);
                setTimeout(() => {
                  mark.style.opacity = '1';
                });
              }
              // 如果元素上有mark，新数据没有children，则移除mark
              if (!('children' in history) && eventItem.children[0]) {
                eventItem.children[0].remove();
              }
              // 如果元素上有mark，新数据也有children，则更新数量
              if ('children' in history && eventItem.children[0]) {
                eventItem.children[0].innerHTML = `${childrenLength}`;
              }
              // 添加事件
              setFunction(eventItem, history);
            }
          } else {
            // 如果eventMap中没有，则创建一个
            const event = document.createElement('div');
            // 绘制
            drawEvent(event, eventLeft, index, history.type);
            // 添加事件
            setFunction(event, history);

            docTimelineCanvas.appendChild(event);
            eventMap.set(history.uploadTime, event);

            if ('children' in history && childrenLength && childrenLength > 1) {
              const mark = document.createElement('div');
              drawMark(mark);
              mark.innerHTML = `${childrenLength}`;
              event.appendChild(mark);
            }
          }
        } else if (eventItem) {
          // 不在显示范围内
          eventItem.style.width = '0';
          eventItem.style.height = '0';
          const mark: any = eventItem.children[0];
          if (mark) {
            mark.style.opacity = '0';
          }
          eventMap.set(history.uploadTime, null);
          setTimeout(() => {
            eventItem.remove();
          }, 200);
        }
      });
      team.beforeHistoryMap = new Map([...team.historyMap.entries()]);
    });
    eventMap.forEach((event: any, key: Date) => {
      if (!historyMapKeys.includes(key) && event) {
        const ele = event;
        ele.style.width = '0';
        ele.style.height = '0';
        const mark: any = ele.children[0];
        if (mark) {
          mark.style.opacity = '0';
        }
        eventMap.set(key, null);
        setTimeout(() => {
          ele.remove();
        }, 200);
      }
    });
  }

  /**
   * @description 绘制图像
   * @param {*} offset 偏移量（百分比）
   * @param {*} times 放大倍数
   */
  draw = (offset: number, times: number) => {
    docCtx.clearRect(0, 0, docCanvas.width, docCanvas.height);
    if (
      CONSTANT.YEAR_TIME_LENGTH / TOTAL_TIME / times <
      CONSTANT.MAX_VIEW_PROPORTION
    ) {
      drawRect(offset, times, EACH_TIME_ARRAY.yearArray as TimeNode[], 'year');
    } else if (
      CONSTANT.MONTH_TIME_LENGTH / TOTAL_TIME / times <
      CONSTANT.MAX_VIEW_PROPORTION
    ) {
      drawRect(
        offset,
        times,
        EACH_TIME_ARRAY.monthArray as TimeNode[],
        'month'
      );
    } else if (
      CONSTANT.WEEK_TIME_LENGTH / TOTAL_TIME / times <
      CONSTANT.MAX_VIEW_PROPORTION
    ) {
      drawRect(offset, times, EACH_TIME_ARRAY.weekArray as TimeNode[], 'week');
    } else if (
      CONSTANT.DAY_TIME_LENGTH / TOTAL_TIME / times <
      CONSTANT.MAX_VIEW_PROPORTION
    ) {
      drawRect(offset, times, EACH_TIME_ARRAY.dayArray as TimeNode[], 'day');
    } else {
      drawRect(offset, times, EACH_TIME_ARRAY.hourArray as TimeNode[], 'hour');
    }
    drawLine();
    setLeftDragTime();
    setRightDragTime();
    drawUpload(times);
  };

  /**
   * @description 调整canvas和scroll的宽度
   */
  function resizeScroll() {
    const sliderWidth = docSlider.offsetWidth;
    docCanvas.width = docTimelineCanvas.clientWidth - CONSTANT.LINE_MARGIN * 2;
    docCanvas.height = (2 * DATA.value.length + 1) * CONSTANT.LINE_HEIGHT;
    docGrip.style.left = '0px';
    docLeftDrag.style.left = '0px';
    docRightDrag.style.left = `${sliderWidth}px`;
    docGrip.style.width = `${sliderWidth}px`;
    left = 0;
    right = 1;
    smallMarginLeft = 0;
    smallMarginRight = 0;
    draw(left, right - left);
  }

  /**
   * @description 左侧滑块移动事件
   * @param {*} event 事件详情
   */
  function leftDragMousemove(event: MouseEvent) {
    const diff = event.x - draglayerX;
    if (diff === 0) return;
    if (TOTAL_TIME <= CONSTANT.HOUR_TIME_LENGTH * CONSTANT.MAX_VIEW_PROPORTION)
      return;
    const sliderLeft = docSlider.offsetLeft;
    const sliderWidth = docSlider.offsetWidth;
    const rightDragLeft = parseInt(
      docRightDrag.style.left?.replace('px', '') || '0',
      10
    );
    const leftDragLeft = parseInt(
      docLeftDrag.style.left?.replace('px', '') || '0',
      10
    );

    // 计算实际位置
    let eventX = leftDragLeft + sliderLeft + diff;

    // 当进入微调，且正在拉长时间线，且微调值不为0时
    if (docGrip.offsetWidth === 20 && diff < 0 && smallMarginLeft !== 0) {
      smallMarginLeft += diff;
    } else {
      // eventX限制条件
      eventX = Math.max(eventX, sliderLeft); // > 0
      eventX = Math.min(eventX, sliderLeft + rightDragLeft - 20); // > 0
      eventX = Math.min(eventX, rightDragLeft + sliderLeft); // < rightDragLeft
      // 显示hour为单位的时间线时，单个时间块最多占整个view的CONSTANT.MAX_VIEW_PROPORTION
      eventX = Math.min(
        eventX,
        (right -
          CONSTANT.HOUR_TIME_LENGTH /
            TOTAL_TIME /
            CONSTANT.MAX_VIEW_PROPORTION) *
          sliderWidth +
          sliderLeft
      );

      // 判断是否进入微调，且正在缩短时间线
      if (docGrip.offsetWidth === 20) {
        smallMarginLeft += diff;
        smallMarginLeft = Math.min(
          smallMarginLeft,
          (right -
            CONSTANT.HOUR_TIME_LENGTH /
              TOTAL_TIME /
              CONSTANT.MAX_VIEW_PROPORTION) *
            sliderWidth +
            sliderLeft -
            eventX
        );
      }

      // 改变视图
      docGrip.style.left = `${eventX - sliderLeft}px`;
      docLeftDrag.style.left = `${eventX - sliderLeft}px`;
      docGrip.style.width = `${rightDragLeft - eventX + sliderLeft}px`;
    }

    smallMarginLeft = Math.max(smallMarginLeft, 0);
    left = (eventX + smallMarginLeft - sliderLeft) / sliderWidth;
    draw(left, right - left);
    draglayerX = event.x;
  }

  /**
   * @description 右侧滑块移动事件
   * @param {*} event 事件详情
   */
  function rightDragMousemove(event: MouseEvent) {
    const diff = event.x - draglayerX;
    if (diff === 0) return;
    if (TOTAL_TIME <= CONSTANT.HOUR_TIME_LENGTH * CONSTANT.MAX_VIEW_PROPORTION)
      return;
    const sliderLeft = docSlider.offsetLeft;
    const sliderWidth = docSlider.offsetWidth;
    const leftDragLeft = parseInt(
      docLeftDrag.style.left?.replace('px', '') || '0',
      10
    );
    const rightDragLeft = parseInt(
      docRightDrag.style.left?.replace('px', '') || '0',
      10
    );

    // 计算实际位置
    let eventX = rightDragLeft + sliderLeft + diff;

    // 当进入微调，且正在拉长时间线，且微调值不为0时
    if (docGrip.offsetWidth === 20 && diff > 0 && smallMarginRight !== 0) {
      smallMarginRight += diff;
    } else {
      // eventX限制条件
      eventX = Math.min(eventX, sliderWidth + sliderLeft);
      eventX = Math.max(eventX, leftDragLeft + sliderLeft + 20);
      eventX = Math.max(
        eventX,
        (left +
          CONSTANT.HOUR_TIME_LENGTH /
            TOTAL_TIME /
            CONSTANT.MAX_VIEW_PROPORTION) *
          sliderWidth +
          sliderLeft
      );

      // 判断是否进入微调，且正在缩短时间线
      if (docGrip.offsetWidth === 20) {
        smallMarginRight += diff;
        smallMarginRight = Math.max(
          smallMarginRight,
          (left +
            CONSTANT.HOUR_TIME_LENGTH /
              TOTAL_TIME /
              CONSTANT.MAX_VIEW_PROPORTION) *
            sliderWidth +
            sliderLeft -
            eventX
        );
      }

      // 改变视图
      docRightDrag.style.left = `${eventX - sliderLeft}px`;
      docGrip.style.width = `${eventX - sliderLeft - leftDragLeft}px`;
    }
    smallMarginRight = Math.min(smallMarginRight, 0);
    right = (eventX + smallMarginRight - sliderLeft) / sliderWidth;
    draw(left, right - left);
    draglayerX = event.x;
  }

  /**
   * @description 中间滑块移动事件
   * @param {*} event 事件详情
   */
  function middleDragMousemove(event: MouseEvent) {
    const diff = event.x - draglayerX;
    if (diff === 0) return;

    const sliderLeft = docSlider.offsetLeft;
    const sliderWidth = docSlider.offsetWidth;
    const dragWidth = docGrip.style.width?.replace('px', '') || '0';
    const leftDragLeft = parseInt(
      docLeftDrag.style.left?.replace('px', '') || '0',
      10
    );

    // 计算实际位置
    let eventX = leftDragLeft + sliderLeft + diff;

    // 限制条件
    eventX = Math.max(eventX, sliderLeft);
    eventX = Math.min(
      eventX,
      sliderWidth - parseInt(dragWidth, 10) + sliderLeft
    );

    const dragLeft = eventX - sliderLeft;
    docGrip.style.left = `${dragLeft}px`;
    docLeftDrag.style.left = `${dragLeft}px`;
    docRightDrag.style.left = `${dragLeft + parseInt(dragWidth, 10)}px`;
    // 利用原始差值计算right
    const difference = right - left;
    left = (dragLeft + smallMarginLeft) / sliderWidth;
    right = left + difference;
    draw(left, right - left);
    draglayerX = event.x;
  }

  /**
   * @description 鼠标抬起事件，删除移动监听
   */
  function mouseUp() {
    document.removeEventListener('mousemove', leftDragMousemove);
    document.removeEventListener('mousemove', rightDragMousemove);
    document.removeEventListener('mousemove', middleDragMousemove);
  }

  /**
   * @description 设置组件响应事件
   */
  function setAction() {
    // 添加鼠标抬起事件
    document.addEventListener('mouseup', mouseUp);
    // 添加鼠标点击事件
    docLeftDrag.onmousedown = (event) => {
      draglayerX = event.x;
      document.addEventListener('mousemove', leftDragMousemove);
    };
    docRightDrag.onmousedown = (event) => {
      draglayerX = event.x;
      document.addEventListener('mousemove', rightDragMousemove);
    };
    docGrip.onmousedown = (event) => {
      draglayerX = event.x;
      document.addEventListener('mousemove', middleDragMousemove);
    };
    // 拖动时禁止图片选中
    // disableImageSelection();
    // 窗口大小变更监听
    window.onresize = resizeScroll;
  }

  /**
   * @description 通过DATA计算常量
   */
  function calculatedConstant() {
    const timeArray = getStartEndTime(DATA.value);
    const [startTime, endTime] = timeArray;
    START_TIME = startTime;
    END_TIME = endTime;
    TOTAL_TIME = END_TIME.getTime() - START_TIME.getTime();
    EACH_TIME_ARRAY = getTimeArray(START_TIME, END_TIME, TOTAL_TIME);
    left = 0;
    right = 1;
    smallMarginLeft = 0;
    smallMarginRight = 0;
  }

  function dataRefresh() {
    calculatedConstant();
    initCanvasAndScroll();
    draw(left, right - left);
  }

  onMounted(() => {
    DATA.value = props.data;
    getDoc();
    setAction();
    dataRefresh();
  });

  watch(
    () => props.data,
    (val) => {
      DATA.value = val;
      dataRefresh();
    }
  );
</script>

<style lang="less" scoped>
  @import '../less/style.less';
  .upline-timeline-legend {
    width: 200px;
    padding-right: 10px;
    padding-top: v-bind(lineWeight);
    min-width: 200px;
    max-width: 500px;
  }

  .upline-selectable {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    background-color: rgb(84, 110, 122);
    margin: v-bind(lineHeight) 5px v-bind(lineHeight) 0;
    padding: 0 16px;
    color: #ffffff;
    height: v-bind(lineHeight);
    line-height: v-bind(lineHeight);
    font-size: 14px;
    cursor: pointer;
    border-radius: 4px;
  }
</style>
